home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Sample Code / AppsToGo / DTS.Draw / Menu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-22  |  14.0 KB  |  548 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** File:        Menu.c
  5. ** Written by:    Eric Soldan
  6. **
  7. ** Copyright © 1990-1993 Apple Computer, Inc.
  8. ** All rights reserved.
  9. */
  10.  
  11. /* You may incorporate this sample code into your applications without
  12. ** restriction, though the sample code has been provided "AS IS" and the
  13. ** responsibility for its operation is 100% yours.  However, what you are
  14. ** not permitted to do is to redistribute the source as "DSC Sample Code"
  15. ** after having made changes. If you're going to re-distribute the source,
  16. ** we require that you make it clear in the source that the code was
  17. ** descended from Apple Sample Code, but that you've made changes. */
  18.  
  19.  
  20.  
  21. /*****************************************************************************/
  22.  
  23.  
  24.  
  25. #include "App.h"            /* Get the application includes/typedefs, etc.    */
  26. #include "App.defs.h"        /* Get various application definitions.            */
  27. #include "App.protos.h"        /* Get the prototypes for application.            */
  28.  
  29. #ifndef __DESK__
  30. #include <Desk.h>
  31. #endif
  32.  
  33. #ifndef __ERRORS__
  34. #include <Errors.h>
  35. #endif
  36.  
  37. #ifndef __MEMORY__
  38. #include <Memory.h>
  39. #endif
  40.  
  41. #ifndef __MENUS__
  42. #include <Menus.h>
  43. #endif
  44.  
  45. #ifndef __TOOLUTILS__
  46. #include <ToolUtils.h>
  47. #endif
  48.  
  49. #ifndef __TREEOBJ2__
  50. #include "TreeObj2.h"
  51. #endif
  52.  
  53. #ifndef __UTILITIES__
  54. #include "Utilities.h"
  55. #endif
  56.  
  57.  
  58.  
  59. /*****************************************************************************/
  60.  
  61.  
  62.  
  63. extern Boolean    gQuitApplication;
  64. extern Boolean    gHasAppleEvents;
  65. extern OSType    gAppWindowType;
  66.  
  67. extern Boolean    gLowOnMem;
  68. extern short    gDialogErr;
  69.  
  70.  
  71.  
  72. /*****************************************************************************/
  73. /*****************************************************************************/
  74.  
  75. #ifdef applec
  76. #pragma segment DTSDrawSeg1
  77. #endif
  78.  
  79. /*****************************************************************************/
  80. /*****************************************************************************/
  81.  
  82.  
  83.  
  84. /* •• Called by DTS.Lib..framework. •• */
  85.  
  86. /* Adjust the menu items.  We allow the DTS.Lib framework to do most of the work
  87. ** for us.  It will walk the menubar, and for each menu in the menubar, it will
  88. ** disable all of the menu items and then call the application at either
  89. ** AdjustMenuItems() (for document and palette windows, or for the no-window case),
  90. ** or DialogAdjustMenuItems() (for modal dialogs).  The application's job is to then
  91. ** turn on menu items that should be enabled to match the current application state.
  92. ** The initial Wannabe code for AdjustMenuItems() calls DoAdjustFileMenu() for the
  93. ** file menu, and DoAdjustEditMenu() for the edit menu.  Any other menus that may
  94. ** be added to Wannabe have all menu items enabled.  This allows menus to be added
  95. ** to the running version of Wannabe and allows them to actually do something.
  96. ** If the top-most window is a dialog, then all menus are disabled except for the
  97. ** edit menu.  Various items in the edit menu are enabled, depending on if there
  98. ** is an active TextEdit control, and what is in the clipboard. */
  99.  
  100. void    DoAdjustMenus(void)
  101. {
  102.     if (DoAdjustMBARMenus(FrontWindow(), rMenuBar))
  103.         DrawMenuBar();
  104. }
  105.  
  106.  
  107.  
  108. /*****************************************************************************/
  109.  
  110.  
  111.  
  112. /* This is called when an item is chosen from the menu bar (after calling
  113. ** MenuSelect or MenuKey).  It performs the right operation for each command.
  114. ** It is good to have both the result of MenuSelect and MenuKey go to one
  115. ** routine like this to keep everything organized. */
  116.  
  117. Boolean    DoMenuCommand(short menuID, short menuItem)
  118. {
  119.     short        saveMode, daRefNum, i;
  120.     Str255        str;
  121.     FileRecHndl    frHndl, newFrHndl;
  122.     WindowPtr    window, clipWind;
  123.     TreeObjHndl    root, cobj;
  124.     OSErr        err;
  125.     Boolean        handled;
  126.  
  127.     handled = true;
  128.  
  129.     window = FrontWindowOfType(kwIsDocument, true);
  130.     if (window)
  131.         frHndl = (FileRecHndl)GetWRefCon(window);
  132.             /* frHndl is valid only if it is one of our windows. */
  133.  
  134.     switch (menuID) {
  135.  
  136.         case mApple:
  137.             switch (menuItem) {
  138.                 case kStdAbout:        /* Bring up alert for About. */
  139.                     NewDocumentWindow(nil, 'ABOT', false);
  140.                     break;
  141.                 default:            /* All non-About items in this menu are DAs. */
  142.                     GetMenuItemText(GetMenuHandle(mApple), menuItem, str);
  143.                     daRefNum = OpenDeskAcc(str);
  144.                     break;
  145.             }
  146.             break;
  147.  
  148.         case mFile:
  149.             switch (menuItem) {
  150.                 case kStdNew:
  151.                     gDialogErr = NewDocumentWindow(&frHndl, gAppWindowType, true);
  152.                     if (gDialogErr)
  153.                         NewDocumentWindow(nil, 'ERR#', false);
  154.                     break;
  155.                 case kStdOpen:
  156.                     err = OpenDocumentWindow(&frHndl, nil, fsRdWrPerm);
  157.                     if ((err) && (err != userCanceledErr)) {
  158.                         gDialogErr = err;
  159.                         NewDocumentWindow(nil, 'ERR#', false);
  160.                     }
  161.                     break;
  162.                 case kStdClose:
  163.                     DisposeOneWindow(window, kClose);
  164.                     break;
  165.                 case kStdSave:
  166.                 case kStdSaveAs:
  167.                     saveMode = (menuItem == kStdSave) ? kSave : kSaveAs;
  168.                     if ((*frHndl)->fileState.refNum == kInvalRefNum)
  169.                         saveMode = kSaveAs;
  170.                     err = SaveDocument(frHndl, window, saveMode);
  171.                     if ((err) && (err != userCanceledErr)) {
  172.                         gDialogErr = err;
  173.                         NewDocumentWindow(nil, 'ERR#', false);
  174.                     }
  175.                     break;
  176.                 case kDuplicate:
  177.                     gDialogErr = DuplicateDocument(frHndl, &newFrHndl);
  178.                     if (!gDialogErr) {
  179.                         gDialogErr = DoNewWindow(newFrHndl, nil,
  180.                                                  FrontWindowOfType(kwIsDocument, true),
  181.                                                  (WindowPtr)-1);
  182.                         if (gDialogErr)
  183.                             DisposeDocument(newFrHndl);
  184.                     }
  185.                     if (gDialogErr)
  186.                         NewDocumentWindow(nil, 'ERR#', false);
  187.                     break;
  188.                 case kStdPageSetup:
  189.                     DoSetCursor(&qd.arrow);
  190.                     PresentStyleDialog(frHndl);
  191.                     break;
  192.                 case kStdPrint:
  193.                     DoSetCursor(&qd.arrow);
  194.                     err = noErr;
  195.                     if (!(*frHndl)->d.doc.fhInfo.printRecValid)
  196.                         err = PresentStyleDialog(frHndl);
  197.                     if (!err) {
  198.                         err = PrintDocument(frHndl, true, true);
  199.                         PrintDocument(nil, false, false);
  200.                     }
  201.                     if ((err) && (err != userCanceledErr)) {
  202.                         gDialogErr = err;
  203.                         NewDocumentWindow(nil, 'ERR#', false);
  204.                     }
  205.                     break;
  206.                 case kStdQuit:
  207.                     gQuitApplication = DisposeAllWindows();
  208.                     break;
  209.             }
  210.             break;
  211.  
  212.         case mEdit:            /* Call SystemEdit for DA editing & MultiFinder. */
  213.             if (!IsDAWindow(window)) {
  214.                 if (menuItem == kClipboard) {
  215.                     clipWind = GetNextWindow(nil, kClipboardFileType);
  216.                     if (clipWind) {
  217.                         ShowHide(clipWind, !((WindowPeek)clipWind)->visible);
  218.                         CleanSendInFront(clipWind, FrontWindowOfType(kwIsDocument, false));
  219.                     }
  220.                     break;
  221.                 }
  222. #if VH_VERSION
  223.                 if (menuItem == kStdViewHier) {
  224.                     handled = false;        /* Let framework automatically open the view hierarchy window. */
  225.                     break;
  226.                 }
  227. #endif
  228.                 switch ((*frHndl)->fileState.sfType) {
  229.                     case kDocFileType:
  230.                         switch (menuItem) {
  231.                             case kStdUndo:
  232.                             case kStdRedo:
  233.                                 DoUndoTask((*frHndl)->d.doc.root, menuItem - kStdUndo, true);
  234.                                 break;
  235.                             case kStdCut:
  236.                             case kStdCopy:
  237.                             case kStdPaste:
  238.                                 DoClipboard(frHndl, menuItem);
  239.                                 break;
  240.                             case kStdClear:
  241.                                 DoDelete(frHndl);
  242.                                 break;
  243.                             case kSelectAll:
  244.                                 BeginContent(window);
  245.                                 root = (*frHndl)->d.doc.root;
  246.                                 for (i = (*root)->numChildren; i;) {
  247.                                     cobj = GetChildHndl(root, --i);
  248.                                     DoTreeObjMethod(cobj, SETSELECTMESSAGE, SELECTON);
  249.                                 }
  250.                                 EndContent(window);
  251.                                 break;
  252.                             default:
  253.                                 handled = false;
  254.                         }
  255.                         break;
  256. #if VH_VERSION
  257.                     case kViewHierFileType:
  258.                         BeginContent(window);
  259.                         switch (menuItem) {
  260.                             case kStdUndo:
  261.                                 CTEUndo();
  262.                                 break;
  263.                             case kStdCut:
  264.                             case kStdCopy:
  265.                             case kStdPaste:
  266.                             case kStdClear:
  267.                                 CTEClipboard(menuItem - kStdCut + 2);
  268.                                 break;
  269.                         }
  270.                         EndContent(window);
  271.                         break;
  272. #endif
  273.                 }
  274.             }
  275.             else SystemEdit(menuItem - 1);
  276.             break;
  277.  
  278.         case mArrange:
  279.             DoArrange(frHndl, menuItem);
  280.             break;
  281.  
  282.         case mOther:
  283.             switch (menuItem) {
  284.                 case kPenSize:
  285.                     NewDocumentWindow(&frHndl, 'PENS', false);
  286.                     break;
  287.                 case kBorderColor:
  288.                 case kContentColor:
  289.                     ChangeColor(frHndl, window, menuItem);
  290.                     break;
  291.             }
  292.             break;
  293.  
  294.         case mToolPalette:
  295.             switch (menuItem) {
  296.                 case -1:
  297.                     handled = false;
  298.                     break;
  299.                 default:
  300.                     SetPaletteTool(menuItem - 1);
  301.                     break;
  302.             }
  303.  
  304.         default:
  305.             handled = false;
  306.             break;
  307.     }
  308.  
  309.     return(handled);
  310. }
  311.  
  312.  
  313.  
  314. /*****************************************************************************/
  315.  
  316.  
  317.  
  318. Boolean    DoAdjustFileMenu(WindowPtr window)
  319. {
  320.     MenuHandle    menu;
  321.     FileRecHndl    frHndl;
  322.     short        enableItem;
  323.  
  324.     menu = GetMenuHandle(mFile);
  325.  
  326.     EnableItem(menu, UnmapMItem(mFile, kStdQuit));            /* Gotta be able to quit. */
  327.  
  328.     if (IsDAWindow(window)) {
  329.         EnableItem(menu, UnmapMItem(mFile, kStdClose));        /* Let DAs do a close from the menu. */
  330.         return(false);
  331.     }
  332.  
  333.     if (!gLowOnMem) {
  334.         EnableItem(menu, UnmapMItem(mFile, kStdNew));
  335.         EnableItem(menu, UnmapMItem(mFile, kStdOpen));
  336.     }
  337.  
  338.     window = FrontWindowOfType(kwIsDocument, true);
  339.     if (window) {
  340.         EnableItem(menu, UnmapMItem(mFile, kStdClose));
  341.         frHndl = (FileRecHndl)GetWRefCon(window);
  342.         if ((*frHndl)->fileState.sfType == kDocFileType) {
  343.             enableItem = GetWindowDirty(window);
  344.             if ((*frHndl)->fileState.refNum == kInvalRefNum)
  345.                 enableItem = true;
  346.             if (enableItem)
  347.                 EnableItem(menu, UnmapMItem(mFile, kStdSave));
  348.             EnableItem(menu, UnmapMItem(mFile, kStdSaveAs));
  349.             EnableItem(menu, UnmapMItem(mFile, kDuplicate));
  350.         }
  351.         EnableItem(menu, UnmapMItem(mFile, kStdPageSetup));
  352.         EnableItem(menu, UnmapMItem(mFile, kStdPrint));
  353.     }
  354.  
  355.     return(false);
  356. }
  357.  
  358.  
  359.  
  360. /*****************************************************************************/
  361.  
  362.  
  363.  
  364. Boolean    DoAdjustEditMenu(WindowPtr window)
  365. {
  366.     MenuHandle        menu;
  367.     Boolean            menuEnabled;
  368.     FileRecHndl        frHndl, frClip;
  369.     WindowPtr        clipWind;
  370.     short            i, undoDepth, numUndos;
  371.     Boolean            haveDocument;
  372.     Str255            str;
  373.     StringPtr        cptr;
  374.     TreeObjHndl        root;
  375.     static Str32    clipboardText[3];
  376.  
  377.     menu = GetMenuHandle(mEdit);
  378.  
  379.     if (IsDAWindow(window)) {
  380.         EnableItem(menu, UnmapMItem(mEdit, kStdUndo));
  381.         EnableItem(menu, UnmapMItem(mEdit, kStdCut));
  382.         EnableItem(menu, UnmapMItem(mEdit, kStdCopy));
  383.         EnableItem(menu, UnmapMItem(mEdit, kStdPaste));
  384.         EnableItem(menu, UnmapMItem(mEdit, kStdClear));
  385.         return(false);
  386.     }
  387.  
  388.     haveDocument = (window = FrontWindowOfType(kwIsDocument, true)) ? true : false;
  389.     frHndl = (haveDocument) ? (FileRecHndl)GetWRefCon(window) : nil;
  390.  
  391. #if VH_VERSION
  392.     if (haveDocument)
  393.         EnableItem(menu, UnmapMItem(mEdit, kStdViewHier));
  394. #endif
  395.  
  396.     EnableItem(menu, UnmapMItem(mEdit, kClipboard));
  397.     if (!clipboardText[0][0]) {
  398.         GetMenuItemText(menu, UnmapMItem(mEdit, kClipboard), str);
  399.         p2c(str);
  400.         for (i = 0; str[i]; ++i)
  401.             if (str[i] == ',')
  402.                 str[i] = 0;
  403.         for (cptr = str, i = 0; i < 3; ++i) {
  404.             c2p((char *)cptr);
  405.             pcpy(clipboardText[i], cptr);
  406.             cptr += (cptr[0] + 1);
  407.         }
  408.     }
  409.     clipWind = GetNextWindow(nil, kClipboardFileType);
  410.     if (clipWind) {
  411.         i = (((WindowPeek)clipWind)->visible) ? 1 : 0;
  412.         pcpy(str, clipboardText[i]);
  413.         pcat(str, clipboardText[2]);
  414.         SetMenuItemText(menu, UnmapMItem(mEdit, kClipboard), str);
  415.     }
  416.  
  417.     if (haveDocument) {
  418.         root = (*frHndl)->d.doc.root;
  419.         switch ((*frHndl)->fileState.sfType) {
  420.             case kDocFileType:
  421.                 GetUndoInfo(frHndl, &undoDepth, &numUndos);
  422.                 if (undoDepth)
  423.                     EnableItem(menu, UnmapMItem(mEdit, kStdUndo));
  424.                 if (undoDepth < numUndos)
  425.                     EnableItem(menu, UnmapMItem(mEdit, kStdRedo));
  426.                 if (mDerefRoot(root)->numSelected) {
  427.                     EnableItem(menu, UnmapMItem(mEdit, kStdCut));
  428.                     EnableItem(menu, UnmapMItem(mEdit, kStdCopy));
  429.                     EnableItem(menu, UnmapMItem(mEdit, kStdClear));
  430.                 }
  431.                 if (clipWind) {
  432.                     frClip = (FileRecHndl)GetWRefCon(clipWind);
  433.                     if ((*((*frClip)->d.doc.root))->numChildren)
  434.                         EnableItem(menu, UnmapMItem(mEdit, kStdPaste));
  435.                 }
  436.                 if (mDerefRoot(root)->numSelected < (*root)->numChildren)
  437.                     EnableItem(menu, UnmapMItem(mEdit, kSelectAll));
  438.                 break;
  439. #if VH_VERSION
  440.             case kViewHierFileType:
  441.                 CTEEditMenu(&menuEnabled, mEdit, UnmapMItem(mEdit, kStdUndo),
  442.                                                  UnmapMItem(mEdit, kStdCut));
  443.                 break;
  444. #endif
  445.             default:
  446.                 CTEEditMenu(&menuEnabled, mEdit, UnmapMItem(mEdit, kStdUndo),
  447.                                                  UnmapMItem(mEdit, kStdCut));
  448.                 break;
  449.         }
  450.     }
  451.  
  452.     return(false);
  453. }
  454.  
  455.  
  456.  
  457. /*****************************************************************************/
  458.  
  459.  
  460.  
  461. Boolean    DoAdjustArrangeMenu(WindowPtr window)
  462. {
  463.     MenuHandle        menu;
  464.     short            i, numChildren, numSelected, cnum, flag;
  465.     Boolean            haveDocument;
  466.     FileRecHndl        frHndl;
  467.     TreeObjHndl        root, chndl;
  468.  
  469.     if (IsDAWindow(window)) return(false);
  470.  
  471.     menu = GetMenuHandle(mArrange);
  472.  
  473.     haveDocument = (window = FrontWindowOfType(kwIsDocument, true)) ? true : false;
  474.     frHndl = (haveDocument) ? (FileRecHndl)GetWRefCon(window) : nil;
  475.  
  476.     for (i = kMoveForward; i <= kUngroup; ++i) CheckItem(menu, i, false);
  477.     if (haveDocument) {
  478.         if ((*frHndl)->fileState.sfType == kDocFileType) {
  479.             root        = (*frHndl)->d.doc.root;
  480.             numChildren = (*root)->numChildren;
  481.             numSelected = mDerefRoot(root)->numSelected;
  482.             if (numSelected) {
  483.                 for (cnum = (*root)->numChildren; cnum;) {
  484.                     chndl = GetChildHndl(root, --cnum);
  485.                     if (DoTreeObjMethod(chndl, GETSELECTMESSAGE, 0))
  486.                         if ((*chndl)->type == GROUPOBJ)
  487.                             EnableItem(menu, kUngroup);
  488.                 }
  489.             }
  490.             if ((numSelected) && (numChildren > 1)) {
  491.                 if ((flag = numSelected) == 1) {
  492.                     chndl = GetChildHndl(root, 0);
  493.                     if (DoTreeObjMethod(chndl, GETSELECTMESSAGE, 0))
  494.                         --flag;
  495.                 }
  496.                 if (flag) {
  497.                     EnableItem(menu, kMoveForward);
  498.                     EnableItem(menu, kMoveToFront);
  499.                 }
  500.                 if ((flag = numSelected) == 1) {
  501.                     chndl = GetChildHndl(root, -1);        /* Last child. */
  502.                     if (DoTreeObjMethod(chndl, GETSELECTMESSAGE, 0))
  503.                         --flag;
  504.                 }
  505.                 if (flag) {
  506.                     EnableItem(menu, kMoveBackward);
  507.                     EnableItem(menu, kMoveToBack);
  508.                 }
  509.             }
  510.             if (numSelected > 1)
  511.                 EnableItem(menu, kGroup);
  512.         }
  513.     }
  514.  
  515.     return(false);
  516. }
  517.  
  518.  
  519.  
  520. /*****************************************************************************/
  521.  
  522.  
  523.  
  524. Boolean    DoAdjustOtherMenu(WindowPtr window)
  525. {
  526.     MenuHandle        menu;
  527.     Boolean            haveDocument;
  528.     FileRecHndl        frHndl;
  529.  
  530.     if (IsDAWindow(window)) return(false);
  531.  
  532.     menu = GetMenuHandle(mOther);
  533.  
  534.     haveDocument = (window = FrontWindowOfType(kwIsDocument, true)) ? true : false;
  535.     frHndl = (haveDocument) ? (FileRecHndl)GetWRefCon(window) : nil;
  536.  
  537.     if (haveDocument) {
  538.         EnableItem(menu, kPenSize);
  539.         EnableItem(menu, kBorderColor);
  540.         EnableItem(menu, kContentColor);
  541.     }
  542.  
  543.     return(false);
  544. }
  545.  
  546.  
  547.  
  548.